package com.glela.common.util;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.glela.common.beans.error.ErrorBean;

/**
 * 验证工具类
 * 
 * @author liujie
 */
public class VerifyUtil
{
	/**
	 * 日期大小和投放时间判断
	 * 
	 * @param map
	 * @author liujie
	 * @return
	 */
	public static Map<String, Object> dateMapCheck(Map<String, Object> map)
	{
		Iterator<Entry<String, Object>> i = map.entrySet().iterator();
		Map<String, Object> errMap = new HashMap<String, Object>();
		String startTime = "";
		String endTime = "";
		String startDate = "";
		String endDate = "";
		while (i.hasNext()) {//只遍历一次,速度快
			Map.Entry<String, Object> ent = i.next();
			if ("startDate" == ent.getKey() || "endDate" == ent.getKey()) {
				String strDate = ent.getValue().toString();
				if (!strDate.matches("^((?:19|20)\\d\\d)-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$")) {
					errMap.put(ent.getKey(), ErrorBean.DATE_FORMATE);
					continue;
				}
			}
			if ("startDate" == ent.getKey()) {
				startDate = ent.getValue().toString();
			}
			if ("endDate" == ent.getKey()) {
				endDate = ent.getValue().toString();
			}
			if ("startTime" == ent.getKey()) {
				startTime = ent.getValue().toString();
			}
			if ("endTime" == ent.getKey()) {
				endTime = ent.getValue().toString();
			}
		}
		//提示用户开始日期必须大于等于结束日期
		if (StringUtil.isNotEmpty(startDate) && StringUtil.isNotEmpty(endDate)) {
			if (DateUtils.compare_date(startDate, endDate) > 0) {
				errMap.put("startDate", ErrorBean.DATE_LOGIC);
			}
		}
		else {
			errMap.put("startDate", ErrorBean.IS_NULL);
		}
		//投放时间段开始时间小于等于结束时间
		if (StringUtil.isNotEmpty(startTime) && StringUtil.isNotEmpty(endTime)) {
			if (CastUtil.castInt(startTime) > CastUtil.castInt(endTime)) {
				errMap.put("startTime", ErrorBean.TIME_LOGIC);
			}
		}
		else {
			errMap.put("startTime", ErrorBean.IS_NULL);
		}

		String nowDate = DateUtils.get24Hour();
		if (CastUtil.castInt(nowDate) > CastUtil.castInt(endTime) && DateUtils.compare_date(DateUtils.getDate(), startDate) == 0) {
			errMap.put("endTime", ErrorBean.DATE_LOGIC);
		}

		return errMap;
	}

	/**
	 * 日期大小和投放时间判断
	 * 
	 * @param map
	 * @author liujie
	 * @return
	 */
	public static Map<String, Object> dateScopeCheck(Map<String, Object> map)
	{
		Iterator<Entry<String, Object>> i = map.entrySet().iterator();
		Map<String, Object> errMap = new HashMap<String, Object>();
		String startTime = "";
		String endTime = "";
		String startDate = "";
		String endDate = "";
		while (i.hasNext()) {//只遍历一次,速度快
			Map.Entry<String, Object> ent = i.next();
			if ("startDate" == ent.getKey() || "endDate" == ent.getKey()||
					"startTime" == ent.getKey() || "endTime" == ent.getKey()) {
				if(ent.getValue()!=null){
					String strDate = ent.getValue().toString();
					if (!strDate.matches("^((?:19|20)\\d\\d)-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$")) {
						errMap.put(ent.getKey(), ErrorBean.DATE_FORMATE);
						continue;
					}
					if ("startDate" == ent.getKey()) {
						startDate = ent.getValue().toString();
					}
					if ("endDate" == ent.getKey()) {
						endDate = ent.getValue().toString();
					}
					if ("startTime" == ent.getKey()) {
						startTime = ent.getValue().toString();
					}
					if ("endTime" == ent.getKey()) {
						endTime = ent.getValue().toString();
					}
				}
			}
		}
		//提示用户开始日期必须大于等于结束日期
		if (StringUtil.isNotEmpty(startDate) && StringUtil.isNotEmpty(endDate)) {
			if (DateUtils.compare_date(startDate, endDate) > 0) {
				errMap.put("startDate", ErrorBean.DATE_LOGIC);
			}
			try {
				 String StartDateSt =DateUtils.format(DateUtils.addDay(DateUtils.parse(startDate,"yyyy-MM-dd"), 30));
				 if (DateUtils.compare_date(endDate, StartDateSt) > 0) {
						errMap.put("startDate", ErrorBean.DATE_LOGIC);
					}
			} catch (ParseException e) {
				e.printStackTrace();
			}
		}
		
		if (StringUtil.isNotEmpty(startTime) && StringUtil.isNotEmpty(endTime)) {
			if (DateUtils.compare_date(startTime, endTime) > 0) {
				errMap.put("startTime", ErrorBean.DATE_LOGIC);
			}
			try {
				 String StartTimeSt =DateUtils.format(DateUtils.addDay(DateUtils.parse(startTime,"yyyy-MM-dd"), 30));
				 if (DateUtils.compare_date(endTime, StartTimeSt) > 0) {
						errMap.put("startDate", ErrorBean.DATE_LOGIC);
					}
			} catch (ParseException e) {
				e.printStackTrace();
			}
		}

		return errMap;
	}
	
	/**
	 * 验证数字 大于0的正整数和小数
	 * 
	 * @param map
	 * @author liujie
	 * @return
	 */
	public static Map<String, Object> floatMapCheck(Map<String, Object> map)
	{
		Iterator<Entry<String, Object>> i = map.entrySet().iterator();
		Map<String, Object> errMap = new HashMap<String, Object>();
		while (i.hasNext()) {//只遍历一次,速度快
			Map.Entry<String, Object> ent = i.next();
			//数字类型验证，不是数字报错
			if ("float" == ent.getKey()) {
				if (!ent.getValue().toString().matches("^(?!(0[0-9]{0,}$))[0-9]{1,}[.]{0,}[0-9]{0,}$")) {
					errMap.put(ent.getKey(), ErrorBean.NUM_FORMAT);
					continue;
				}
			}

		}
		return errMap;
	}

	/**
	 * 循环验证数字 大于0的正整数
	 * 
	 * @param map
	 * @author liujie
	 * @return
	 */
	public static Map<String, Object> integerMapCheck(Map<String, Object> map)
	{
		Iterator<Entry<String, Object>> i = map.entrySet().iterator();
		Map<String, Object> errMap = new HashMap<String, Object>();
		while (i.hasNext()) {//只遍历一次,速度快
			Map.Entry<String, Object> ent = i.next();
			//数字类型验证，不是数字报错
			if ("integer" == ent.getKey()) {
				if (!ent.getValue().toString().matches("^[0-9]*[1-9][0-9]*$")) {
					errMap.put(ent.getKey(), ErrorBean.NUM_FORMAT);
					continue;
				}
			}
		}
		return errMap;
	}

	/**
	 * 循环非空验证
	 * 
	 * @param map
	 * @author liujie
	 * @return
	 */
	public static Map<String, Object> notNullMapCheck(Map<String, Object> map)
	{
		Iterator<Entry<String, Object>> i = map.entrySet().iterator();
		Map<String, Object> errMap = new HashMap<String, Object>();
		while (i.hasNext()) {//只遍历一次,速度快
			Map.Entry<String, Object> ent = i.next();
			//非空验证
			if (ent.getValue() == null || ent.getValue()=="") {
				errMap.put(ent.getKey(), ErrorBean.IS_NULL);
				continue;
			}
		}
		return errMap;
	}

	/**
	 * 封装错误信息
	 * 
	 * @param msg
	 * @return
	 */
	public static void packErrorInfo(ErrorBean error, List<ErrorBean> errors)
	{
		if (error != null) {
			errors.add(error);
		}
	}

	/**
	 * 循环验证正整数数字
	 * 
	 * @param map
	 * @author 
	 * @return
	 */
	public static Map<String, Object> positiveIntegerMapCheck(Map<String, Object> map)
	{
		Iterator<Entry<String, Object>> i = map.entrySet().iterator();
		Map<String, Object> errMap = new HashMap<String, Object>();
		while (i.hasNext()) {//只遍历一次,速度快
			Map.Entry<String, Object> ent = i.next();
			//数字类型验证，不是数字报错
			if ("integer" == ent.getKey()) {
				if (!ent.getValue().toString().matches("^[0-9]*[0-9][0-9]*$")) {
					errMap.put(ent.getKey(), ErrorBean.NUM_FORMAT);
					continue;
				}
			}
		}
		return errMap;
	}

	/**
	 * 批量校验
	 * 
	 * @param params
	 *            （K:参数名 V：参数值）
	 * @return
	 */
	public static List<ErrorBean> verifyAllParam(Map<String, String> params)
	{
		List<ErrorBean> result = new ArrayList<>();
		List<ErrorBean> errors = new ArrayList<>();
		Set<String> paramNames = params.keySet();

		String startDate = null;
		String endDate = null;
		for (String paramName : paramNames) {
			String paramValue = params.get(paramName);
			errors.add(VerifyUtil.verifyNotNull(paramName, paramValue));
			if (paramName.toUpperCase().indexOf("DATE") != -1) {//日期额外处理
				if (paramName.toUpperCase().indexOf("START") != -1) {
					startDate = paramValue;
				}
				if (paramName.toUpperCase().indexOf("END") != -1) {
					endDate = paramValue;
				}
			}
			else if (paramName.toUpperCase().indexOf("NUM") != -1 || paramName.toUpperCase().indexOf("AMOUNT") != -1) {
				errors.add(VerifyUtil.verifyNum(paramName, paramValue));
			}
		}

		if (startDate != null || endDate != null) {
			if (startDate != null && endDate != null) {
				errors.addAll(VerifyUtil.verifyDate(startDate, endDate));
			}
			else {
				errors.add(new ErrorBean(ErrorBean.OTHER, null, "开始日期和结束日期必须同时校验"));
			}
		}
		for (ErrorBean error : errors) {
			if (error != null) {
				result.add(error);
			}
		}

		return result;
	}

	/**
	 * 判断视频投放总额是否大于用户总额
	 * 
	 * @param inputPrice
	 * @param minPrice
	 * @return
	 */
	public static ErrorBean verifyBalance(Double inputBalance, Double userBalance)
	{
		if (inputBalance > userBalance) {
			return new ErrorBean(ErrorBean.OTHER, null, "投放金额不能大于您的总金额！");
		}
		return null;
	}

	/**
	 * 验证日期
	 * 
	 * @param startDate
	 * @param endDate
	 * @return
	 */
	public static List<ErrorBean> verifyDate(String startDate, String endDate)
	{
		List<ErrorBean> errors = new ArrayList<>();
		Date now = new Date();
//		String nowTimeStr = DateUtils.dateFormat(now, "yyyy-MM-dd");
		boolean startFormat = startDate.matches("[1-2][0-9]{3}-[0-1][0-9]-[0-3][0-9]");
		boolean endFormat = endDate.matches("[1-2][0-9]{3}-[0-1][0-9]-[0-3][0-9]");
		if (!startFormat) {
			errors.add(new ErrorBean(ErrorBean.DATE_FORMATE, null, "开始日期格式错误"));
		}
		if (!endFormat) {
			errors.add(new ErrorBean(ErrorBean.DATE_FORMATE, null, "结束日期格式错误"));
		}
		if (startFormat && endFormat) {
			try {
				Date start = DateUtils.parse(startDate, "yyyy-MM-dd");
				Date end = DateUtils.parse(endDate, "yyyy-MM-dd");
				if (start.before(now)) {
					//					if (startDate.equals(nowTimeStr)) {
					//						
					//					}else{
					//						errors.add(new ErrorBean(ErrorBean.DATE_LOGIC, null, "开始日期不能小于当前日期"));
					//					}
				}
				else if (start.after(end)) {
					errors.add(new ErrorBean(ErrorBean.DATE_LOGIC, null, "开始日期不能大于结束日期"));
				}
			}
			catch (ParseException e) {
				errors.add(new ErrorBean(ErrorBean.DATE_FORMATE, null, "日期格式错误"));
			}
		}
		return errors;

	}

	/**
	 * 验证值相等
	 * 
	 * @param paramName
	 * @param oldValue
	 * @param newValue
	 * @param paramDesc
	 * @return
	 */
	public static ErrorBean verifyEquals(String paramName, String oldValue, String newValue, String paramDesc)
	{
		if (oldValue != newValue && !oldValue.equals(newValue)) {
			return new ErrorBean(ErrorBean.STRING_EQUALS, paramName, paramDesc + "两次" + paramName + "输入不一致");
		}
		else {
			return null;
		}
	}

	/**
	 * 验证非空
	 * 
	 * @param param
	 * @param paramName
	 * @return
	 */
	public static ErrorBean verifyNotNull(String paramName, String paramValue)
	{

		if (paramValue == null || paramValue.trim().equals("")) {
			return new ErrorBean(ErrorBean.IS_NULL, paramName, paramName + "不能为空");
		}
		else {
			return null;
		}

	}

	/**
	 * 验证非空
	 * 
	 * @param param
	 * @param paramName
	 * @return
	 */
	public static ErrorBean verifyNotNull(String paramName, String paramValue, String paramDesc)
	{

		if (paramValue == null || paramValue.trim().equals("")) {
			return new ErrorBean(ErrorBean.IS_NULL, paramName, paramDesc + "不能为空");
		}
		else {
			return null;
		}

	}

	/**
	 * 验证数字
	 * 
	 * @param param
	 * @param paramName
	 * @return
	 */
	public static ErrorBean verifyNum(String paramName, String paramValue)
	{

		if (!paramValue.matches("[0-9]+(.[0-9]+)?")) {
			return new ErrorBean(ErrorBean.NUM_FORMAT, paramName, paramName + "非数字类型");
		}
		else {
			return null;
		}

	}

	/**
	 * 验证单个用户可领取次数是否大于总播放次数
	 * 
	 * @param inputPrice
	 * @param minPrice
	 * @return
	 */
	public static ErrorBean verifyPlayNum(int userPlayNum, int totalPlayNum)
	{
		if (userPlayNum > totalPlayNum) {
			return new ErrorBean(ErrorBean.OTHER, null, "单次用户领取次数不能大于总播放次数！");
		}
		return null;
	}

	/**
	 * 判断输入单价是否大于系统最低单价
	 * 
	 * @param inputPrice
	 * @param minPrice
	 * @return
	 */
	public static ErrorBean verifyPrice(double inputPrice, double minPrice)
	{
		if (minPrice > inputPrice) {
			return new ErrorBean(ErrorBean.OTHER, null, "投放单价小于系统设置最低单价");
		}
		return null;
	}

	/**
	 * 正则表达式校验
	 * 
	 * @param paramName
	 * @param paramValue
	 * @param pattern
	 *            正则表达式
	 * @param paramDesc
	 * @return
	 */
	public static ErrorBean verifyRegExp(String paramName, String paramValue, String pattern, String paramDesc)
	{
		Pattern p = Pattern.compile(pattern);
		Matcher m = p.matcher(paramValue);
		if (m.matches()) {
			return null;
		}
		else {
			return new ErrorBean(ErrorBean.REGEXP_MATCHER, paramName, paramDesc);
		}
	}

	/**
	 * 功能：验证字符串长度是否符合要求，一个汉字等于两个字符
	 * 
	 * @param strParameter
	 *            要验证的字符串
	 * @param limitLength
	 *            验证的长度
	 * @return 符合长度null 超出范围ErrorBean
	 */
	public static ErrorBean verifyStrByLength(String paramName, String paramValue, String paramDesc, int minLength,
			int limitLength)
	{
		int temp_int = 0;
		String chinese = "[\u0391-\uFFE5]";
		/* 获取字段值的长度，如果含中文字符，则每个中文字符长度为2，否则为1 */
		for (int i = 0; i < paramValue.length(); i++) {
			/* 获取一个字符 */
			String temp = paramValue.substring(i, i + 1);
			/* 判断是否为中文字符 */
			if (temp.matches(chinese)) {
				/* 中文字符长度为2 */
				temp_int += 2;
			}
			else {
				/* 其他字符长度为1 */
				temp_int += 1;
			}
		}
		if (temp_int > limitLength || temp_int < minLength) {
			return new ErrorBean(ErrorBean.STRING_LENGTH, paramName, paramDesc + "长度应在" + minLength + "~" + limitLength + "个字符之间");
		}
		else {
			return null;
		}
	}

	/**
	 * 验证投放时段
	 * 
	 * @param startDate
	 * @param endDate
	 * @return
	 */
	public static List<ErrorBean> verifyTime(String startTime, String endTime)
	{
		List<ErrorBean> errors = new ArrayList<>();
		if (StringUtil.isNotEmpty(startTime) && StringUtil.isNotEmpty(endTime)) {
			int st = -1;
			try {
				st = Integer.parseInt(startTime);
			}
			catch (NumberFormatException e) {
				errors.add(new ErrorBean(ErrorBean.TIME_LOGIC, null, "开始时段格式错误"));
			}
			int et = -1;
			try {
				et = Integer.parseInt(endTime);
			}
			catch (NumberFormatException e) {
				errors.add(new ErrorBean(ErrorBean.TIME_LOGIC, null, "结束时段格式错误"));
			}

			if (!(st >= 0 && st <= 23)) {
				errors.add(new ErrorBean(ErrorBean.TIME_LOGIC, null, "结束时段设置错误"));
			}

			if (!(et > 0 && st <= 23)) {
				errors.add(new ErrorBean(ErrorBean.TIME_LOGIC, null, "开始时段设置错误"));
			}

			if (et == st) {
				errors.add(new ErrorBean(ErrorBean.TIME_LOGIC, null, "开始时段不能等于结束时段"));
			}

			if (st > et) {
				errors.add(new ErrorBean(ErrorBean.TIME_LOGIC, null, "结束时段应当大于开始时段！"));
			}

		}
		else if (StringUtil.isEmpty(startTime) && StringUtil.isNotEmpty(endTime)) {
			errors.add(new ErrorBean(ErrorBean.TIME_LOGIC, null, "请填写开始时段"));
		}
		else if (StringUtil.isNotEmpty(startTime) && StringUtil.isEmpty(endTime)) {
			errors.add(new ErrorBean(ErrorBean.TIME_LOGIC, null, "请填写结束时段"));
		}
		return errors;

	}

	public static ErrorBean verifyVarcharByLength(String paramName, String paramValue, String paramDesc, int minLength,
			int limitLength)
	{
		int temp_int = paramValue.length();
		if (temp_int > limitLength || temp_int < minLength) {
			return new ErrorBean(ErrorBean.STRING_LENGTH, paramName, paramDesc + "长度应在" + minLength + "~" + limitLength + "个字符之间");
		}
		else {
			return null;
		}
	}

}